import yaml

from commons.request_util import logger


# 读取测试用例
def read_testcase_yaml(yaml_path):
    # 读取 yaml 测试用例
    with open(yaml_path, encoding="utf-8", mode="r") as f:
        case_list = yaml.safe_load(f)
        # 如果用例列表长度大于等于2，说明是流程用例
        if len(case_list) >= 2:
            return [case_list]  # [[{},{}]]  解包  [{},{}]
        else:
            # 如果用例中包含 parametrize 字段
            if "parametrize" in dict(*case_list).keys():
                # 如果 parametrize 不为空，说明存在正反用例
                if case_list[0]["parametrize"]:
                    new_caseInfo = ddts(*case_list, yaml_path.name)
                    return new_caseInfo  # [{},{},{}]  #数据驱动用例   解包之后：{},{},{}
                else:
                    return case_list
            else:
                return case_list  # [{}]  #单接口用例，解包{}


# 处理parametrize数据驱动，{parametrize}改造成[{},{},{}]
def ddts(case: dict, yaml_name):
    param_list = case["parametrize"]
    if param_list:  # 判断 parametrize 不为空
        # 获取第一行字段列表长度
        name_length = len(param_list[0])
        # 遍历每一列，第一列为字段列表，剩下的都是数据
        for param_line in param_list:
            # 判断每行长度和字段的长度必须一致
            if len(param_line) != name_length:
                logger.error(yaml_name + "：parametrize数据驱动中数据或名称长度不一致\n")
                break
            else:
                # 如果长度没有问题，new 一个空列表
                new_caseInfo_list = []
                # 把字典转化为字符串,因为只有字符串才可以替换
                case_str = yaml.dump(case)
                # 循环遍历数据列表（遍历从1开始，0为字段列表）
                for x in range(1, len(param_list)):  # param_list [[],[],[],[]]
                    # 执行之前先保存一份 case
                    raw_case = case_str
                    # 列 name_length
                    for y in range(0, name_length):
                        # 处理数据类型，如果是数字类型的字符串则加一对单引号
                        if isinstance(param_list[x][y], str) and param_list[x][y].isdigit():
                            param_list[x][y] = "'" + param_list[x][y] + "'"
                        # 替换
                        raw_case = raw_case.replace("$ddt{" + param_list[0][y] + "}", str(param_list[x][y]))
                    # 将替换后的新数据转换成 yaml 数据
                    raw_case_dict = yaml.safe_load(raw_case)
                    # 将替换后的测试用例，去掉正反用例列表，转换成正式用例
                    raw_case_dict.pop("parametrize")
                    # 将正式用例加入新的list中
                    new_caseInfo_list.append(raw_case_dict)
                return new_caseInfo_list
    else:
        return [case]
